package com.example.project.projectspringcloud.utils;

import org.apache.commons.httpclient.URIException;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.util.URIUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.*;
import java.util.Map.Entry;

/**
 * Http工具类
 * Created by Wangys 2018年4月17日
 */
public class HttpUtil {

    public final static String STREAM_DATA_NAME = "streamData";
    private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(HttpUtil.class);
    private final static HttpClient HTTP_CLIENT = initHttpClient();

    /**
     * 工具类禁止实例化
     */
    private HttpUtil() {
    }

    private static HttpClient initHttpClient() {
        PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
        // TODO put in propertifile
        connectionManager.setMaxTotal(1000);
        connectionManager.setDefaultMaxPerRoute(connectionManager.getMaxTotal());

        return HttpClients.custom().setConnectionManager(connectionManager).build();
    }

    /**
     * 以get方式提交请求
     *
     * @param server
     * @return
     */
    public static String get(String server) {
        return get(URI.create(server));
    }

    /**
     * 以get方式提交请求
     *
     * @param action
     * @return
     */
    public static String get(String server, String action) {
        return get(URI.create(server + action));
    }

    /**
     * 以get方式提交请求
     *
     * @param action
     * @param args
     * @return
     */
    public static String get(String server, String action, String... args) {
        String url = server + createURI(action, args);
        return get(URI.create(url));
    }

    /**
     * 以post方式发送请求
     *
     * @param server
     * @return
     */
    public static String post(String server) {
        return post(URI.create(server), null);
    }

    /**
     * 以post方式提交请求
     *
     * @param action
     * @return
     */
    public static String post(String server, String action) {
        return post(URI.create(server + action), null);
    }

    /**
     * 以post方式提交请求
     *
     * @param action
     * @return
     */
    public static String post(String server, String action, String... args) {
        return post(URI.create(server + createURI(action, args)), null);
    }

    /**
     * 以post方式提交请求
     *
     * @param server
     * @param action
     * @param args
     * @return
     */
    public static String post(String server, String action, Map<String, String> args) {
        return post(URI.create(server + action), args);
    }

    /**
     * 以post方式发送请求
     *
     * @param action
     * @param args
     * @return
     */
    public static String post(String action, Map<String, String> args) {
        return post(URI.create(action), args);
    }

    public static String postObj(String action, Map<String, Object> args) {
        return postObj(URI.create(action), args);
    }

    /**
     * 以get方式提交请求
     *
     * @param uri
     * @return
     */
    public static String get(URI uri, Header... headers) {
        // LOGGER.info("发起请求： uri: {}, headers: {}", uri, Arrays.toString(headers));
        HttpGet get = new HttpGet(uri);
        String result = null;
        if (headers != null && headers.length > 0) {
            get.setHeaders(headers);
        }
        try {
            long start = System.currentTimeMillis();
            HttpResponse response = HTTP_CLIENT.execute(get);
            HttpEntity entity = response.getEntity();
            // LOGGER.info("请求响应： {}", response.getStatusLine().getStatusCode());
            result = analysisResp(entity.getContent());
            // LOGGER.info("请求成功！ uri: {}, response: {}", uri, result);
            EntityUtils.consume(entity);
            long spend = System.currentTimeMillis() - start;
            if (spend > 1000) {
            }
        } catch (IOException e) {
            LOGGER.error("请求失败! uri: {}, headers: {}", uri, Arrays.toString(headers));
            LOGGER.error(e.getMessage(), e);
        } finally {
            get.releaseConnection();
        }
        // Logger.i(HttpUtil.class, "get request : "+ uri + ", result ：" + result);
        return result;
    }

    /**
     * 以post方式发送请求
     *
     * @param uri
     * @param args
     * @return
     */
    public static String post(URI uri, Map<String, String> args, Header... headers) {
        if (LOGGER.isInfoEnabled()) {
            LOGGER.info("发起请求 ! uri: {}, args: {}, headers: {}", uri, JsonUtil.obj2Json(args), Arrays.toString(headers));
        }
        String result = null;
        HttpPost post = new HttpPost(uri);
        List<NameValuePair> nvps = new ArrayList();
        if (args != null && args.size() > 0) {
            Set<Entry<String, String>> entrys = args.entrySet();
            for (Entry<String, String> enrty : entrys) {
                nvps.add(new BasicNameValuePair(enrty.getKey(), enrty.getValue()));
            }
        }
        if (headers != null && headers.length > 0) {
            post.setHeaders(headers);
        }

        try {
            long start = System.currentTimeMillis();
            post.setEntity(new UrlEncodedFormEntity(nvps, Charset.forName("UTF-8")));
            HttpResponse response = HTTP_CLIENT.execute(post);
            LOGGER.info("请求响应 ! uri: {}, code: {}", uri, response.getStatusLine().getStatusCode());
            HttpEntity entity = response.getEntity();
            result = analysisResp(entity.getContent());
            LOGGER.info("请求成功 ! uri: {}, result: {}", uri, result);
            EntityUtils.consume(entity);
            long spend = System.currentTimeMillis() - start;
            if (spend > 1000) {
            }
        } catch (Exception e) {
            LOGGER.error("请求失败 ! uri: {}, args: {}, headers: {}", uri, JsonUtil.obj2Json(args), Arrays.toString(headers));
            LOGGER.error(e.getMessage(), e);
        } finally {
            post.releaseConnection();
        }
        // Logger.i(HttpUtil.class, "post request : " + uri + ", result : " + result);
        return result;
    }

    /**
     * 以post方式发送请求
     *
     * @param uri
     * @param args
     * @return
     */
    public static String postObj(URI uri, Map<String, Object> args, Header... headers) {
        if (LOGGER.isInfoEnabled()) {
            LOGGER.info("发起请求 ! uri: {}, args: {}, headers: {}", uri, JsonUtil.obj2Json(args), Arrays.toString(headers));
        }
        String result = null;
        HttpPost post = new HttpPost(uri);
        List<NameValuePair> nvps = new ArrayList();
        if (args != null && args.size() > 0) {
            Set<Entry<String, Object>> entrys = args.entrySet();
            for (Entry<String, Object> enrty : entrys) {
                nvps.add(new BasicNameValuePair(enrty.getKey().toString(), enrty.getValue().toString()));
            }
        }
        if (headers != null && headers.length > 0) {
            post.setHeaders(headers);
        }

        try {
            long start = System.currentTimeMillis();
            post.setEntity(new UrlEncodedFormEntity(nvps, Charset.forName("UTF-8")));
            HttpResponse response = HTTP_CLIENT.execute(post);
            LOGGER.info("请求响应 ! uri: {}, code: {}", uri, response.getStatusLine().getStatusCode());
            HttpEntity entity = response.getEntity();
            result = analysisResp(entity.getContent());
            LOGGER.info("请求成功 ! uri: {}, result: {}", uri, result);
            EntityUtils.consume(entity);
            long spend = System.currentTimeMillis() - start;
            if (spend > 1000) {
            }
        } catch (Exception e) {
            LOGGER.error("请求失败 ! uri: {}, args: {}, headers: {}", uri, JsonUtil.obj2Json(args), Arrays.toString(headers));
            LOGGER.error(e.getMessage(), e);
        } finally {
            post.releaseConnection();
        }
        // Logger.i(HttpUtil.class, "post request : " + uri + ", result : " + result);
        return result;
    }

    /**
     * 以post方式发送请求
     *
     * @param uri
     * @param input
     * @return
     */
    public static String postStream(URI uri, String input, Header... headers) {
        LOGGER.info("发起请求! uri: {}, input: {}, headers: {}", uri, input, Arrays.toString(headers));
        HttpPost post = new HttpPost(uri);
        String result = null;
        if (headers != null && headers.length > 0) {
            post.setHeaders(headers);
        }
        try {
            long start = System.currentTimeMillis();

            if (input != null) {
                post.setEntity(new StringEntity(input, "UTF-8"));
            }
            HttpResponse response = HTTP_CLIENT.execute(post);
            LOGGER.info("请求响应码! uri: {}, code: {} ", uri, response.getStatusLine().getStatusCode());
            HttpEntity entity = response.getEntity();
            result = analysisResp(entity.getContent());
            LOGGER.info("请求成功 ! uri: {}, result: {}", uri, result);
            EntityUtils.consume(entity);
            long spend = System.currentTimeMillis() - start;
            if (spend > 1000) {
            }
        } catch (Exception e) {
            LOGGER.error("请求失败 ! uri: {}, input: {}, headers: {}", uri, input, Arrays.toString(headers));
            LOGGER.error(e.getMessage(), e);
        } finally {
            post.releaseConnection();
        }
        // Logger.i(HttpUtil.class, "post request : " + uri + ", result : " + result);
        return result;
    }

    /**
     * 以post方式发送请求
     *
     * @param uri
     * @return
     */
    public static String post(URI uri, Header... headers) {
        return postStream(uri, null, headers);
    }

    /**
     * 解析接口返回数据
     *
     * @param inputStream
     * @return
     * @throws IOException
     */
    private static String analysisResp(InputStream inputStream) throws IOException {
        // 响应正文
        StringBuilder result = new StringBuilder();
        BufferedReader br = new BufferedReader(new InputStreamReader(
                inputStream, "utf-8"));
        String temp = "";
        while ((temp = br.readLine()) != null) {
            result.append(temp);
        }
        return result.toString();
    }

    /**
     * 以post方式提交请求
     *
     * @param action
     * @return
     */
    public static String postStream(String server, String action, String input, String... args) {
        return postStream(URI.create(server + createURI(action, args)), input);
    }

    /**
     * 替换URL中的参数
     *
     * @param uri
     * @param args
     * @return
     */
    private static String createURI(String uri, String... args) {
        return String.format(uri, args);
    }

    /**
     * 根据资源名，获取真实URL
     *
     * @param action
     * @param args
     * @return
     */
    public static String getURI(String action, String... args) {
        return createURI(action, args);
    }

    /**
     * 根据资源名，获取真实URI
     *
     * @param server
     * @param action
     * @param args
     * @return
     */
    public static String getURL(String server, String action, String... args) {
        return server + createURI(action, args);
    }

    /**
     * 从request中获取请求参数
     *
     * @param request
     * @return
     */
    public static String getStringFromRequest(javax.servlet.http.HttpServletRequest request) {
        return getStringFromRequest(request, false);
    }

    /**
     * 从request中获取请求参数
     *
     * @param request
     * @param isStream
     * @return
     */
    public static String getStringFromRequest(javax.servlet.http.HttpServletRequest request, boolean isStream) {
        StringBuilder sbd = new StringBuilder();
        if (isStream) {
            try {
                BufferedReader in = null;
                try {
                    in = new BufferedReader(new InputStreamReader(request.getInputStream()));
                    String line = null;
                    while ((line = in.readLine()) != null) {
                        sbd.append(line);
                    }
                } catch (Exception e) {
                } finally {
                    if (in != null) {
                        try {
                            in.close();
                        } catch (IOException e) {
                        }
                    }
                }
            } catch (Exception e) {
            }
        } else {
            // 将reqeust中的所有请求参数拼装成URL风格参数
            for (Iterator<Entry<String, String[]>> iter = request.getParameterMap().entrySet().iterator(); iter.hasNext(); ) {
                Entry<String, String[]> e = iter.next();
                String[] values = e.getValue();
                String valueStr = "";
                for (int i = 0; i < values.length; i++) {
                    valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
                }
                sbd.append("&").append(e.getKey()).append("=").append(valueStr);
            }
        }
        return sbd.length() > 0 ? sbd.substring(1) : null;
    }

    /**
     * 从request中获取请求参数
     *
     * @param request
     * @return
     */
    public static Map<String, String> getMapFromRequest(javax.servlet.http.HttpServletRequest request) {
        return getMapFromRequest(request, false);
    }

    /**
     * 从request中获取请求参数
     *
     * @param request
     * @param isStream
     * @return
     */
    public static Map<String, String> getMapFromRequest(javax.servlet.http.HttpServletRequest request, boolean isStream) {
        Map<String, String> map = new HashMap<>();
        if (isStream) {
            try {
                BufferedReader in = null;
                try {
                    in = new BufferedReader(new InputStreamReader(request.getInputStream()));
                    String line = null;
                    String result = "";
                    while ((line = in.readLine()) != null) {
                        result += line;
                    }
                    map.put(STREAM_DATA_NAME, result);
                } catch (Exception e) {
                } finally {
                    if (in != null) {
                        try {
                            in.close();
                        } catch (IOException e) {
                        }
                    }
                }
            } catch (Exception e) {
            }
        } else {
            // 将reqeust中的所有请求参数放入map中
            for (Iterator<Entry<String, String[]>> iter = request.getParameterMap().entrySet().iterator(); iter.hasNext(); ) {
                Entry<String, String[]> e = iter.next();
                String[] values = e.getValue();
                String valueStr = "";
                for (int i = 0; i < values.length; i++) {
                    valueStr = (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
                }
                map.put(e.getKey(), valueStr);
            }
        }
        return map;
    }

    public static String postParams(String url, Map<String, String> params) {
        if (LOGGER.isInfoEnabled()) {
            LOGGER.info("发起请求: uri: {}, param: {}", url, JsonUtil.obj2Json(params));
        }
        URL u = null;
        HttpURLConnection conn = null;
        // 构建请求参数
        StringBuffer sb = new StringBuffer();
        if (params != null) {
            for (Entry<String, String> e : params.entrySet()) {
                sb.append(e.getKey());
                sb.append("=");
                sb.append(e.getValue());
                sb.append("&");
            }
            sb.substring(0, sb.length() - 1);
        }

        try {
            u = new URL(url);
            conn = (HttpURLConnection) u.openConnection();
            conn.setRequestMethod("POST");
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);
            // 需要设置
            conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

            OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8");
            out.write(sb.toString());
            out.flush();
            out.close();
        } catch (Exception e) {
            LOGGER.error("请求失败 ! uri: {}, paramm: {}", url, JsonUtil.obj2Json(params));
            LOGGER.error(e.getMessage(), e);
            throw new RuntimeException(e);
        } finally {
            if (conn != null) {
                conn.disconnect();
            }
        }
        LOGGER.info("构造请求参数: {}", sb.toString());
        StringBuffer buffer = new StringBuffer();
        try {
            LOGGER.info("请求响应码! uri: {}, code: {} ", url, conn.getResponseCode());
            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream(), "UTF-8"));
            String temp;
            while ((temp = br.readLine()) != null) {
                buffer.append(temp);
                buffer.append("\n");
            }
            LOGGER.info("请求成功 ! uri: {}, result: {}", url, buffer.toString());
        } catch (Exception e) {
            LOGGER.error("请求失败 ! uri: {}, paramm: {}", url, JsonUtil.obj2Json(params));
            LOGGER.error(e.getMessage(), e);
        }

        return buffer.toString();
    }

    public static String doGet(String url, String queryString) {
        String response = null;
        org.apache.commons.httpclient.HttpClient client = new org.apache.commons.httpclient.HttpClient();
        GetMethod method = new GetMethod(url);
        method.getParams().setParameter("http.protocol.content-charset", "UTF-8");

        try {
            if (StringUtils.isNotBlank(queryString)) {
                method.setQueryString(URIUtil.encodeQuery(queryString));
            }

            client.executeMethod(method);
            if (method.getStatusCode() == 200) {
                response = method.getResponseBodyAsString();
            }
        } catch (URIException var10) {
            ;
        } catch (IOException var11) {
            ;
        } finally {
            method.releaseConnection();
        }

        return response;
    }

    public static String doPost(String url, Map<String, String> params) {
        LOGGER.info("Post Url:" + url + ",Params:" + params);
        StringBuffer result = new StringBuffer();
        org.apache.commons.httpclient.HttpClient client = new org.apache.commons.httpclient.HttpClient();
        PostMethod method = new PostMethod(url);
        method.getParams().setParameter("http.protocol.content-charset", "UTF-8");
        if (!ObjectUtil.isNull(params)) {
            org.apache.commons.httpclient.NameValuePair[] e = new org.apache.commons.httpclient.NameValuePair[params.size()];
            int str = 0;

            Map.Entry entry;
            for (Iterator i$ = params.entrySet().iterator(); i$.hasNext(); e[str++] = new org.apache.commons.httpclient.NameValuePair((String) entry.getKey(), (String) entry.getValue())) {
                entry = (Map.Entry) i$.next();
            }

            method.setRequestBody(e);
        }

        try {
            client.executeMethod(method);
            if (method.getStatusCode() == 200) {
                BufferedReader var14 = new BufferedReader(new InputStreamReader(method.getResponseBodyAsStream(), "UTF-8"));
                String var15 = null;

                while ((var15 = var14.readLine()) != null) {
                    result.append(var15);
                }
            }
        } catch (IOException var12) {
            ;
        } finally {
            method.releaseConnection();
        }

        LOGGER.debug("Post Return:" + result.toString());
        return result.toString();
    }

    public static String doPostXml(String urlStr, String xmlStr) {
        String result = null;
        try {
            // 创建连接
            URL urlClient = new URL(urlStr);
            HttpURLConnection connection = (HttpURLConnection) urlClient.openConnection();
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setRequestMethod("POST");
            connection.setUseCaches(false);
            connection.setInstanceFollowRedirects(true);
            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
            connection.connect();

            // POST请求
            DataOutputStream out = new DataOutputStream(connection.getOutputStream());
            out.write(xmlStr.getBytes());
            out.flush();
            out.close();

            // 读取响应
            BufferedReader reader = new BufferedReader(new InputStreamReader(
                    connection.getInputStream()));
            String lines;
            StringBuffer sb = new StringBuffer("");
            while ((lines = reader.readLine()) != null) {
                lines = new String(lines.getBytes(), "utf-8");
                sb.append(lines);
            }
            reader.close();
            // 断开连接
            connection.disconnect();
            result = sb.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    public static String testGet(String server, String name, String value) {
        return test(URI.create(server), name, value);
    }

    /**
     * 以get方式提交请求
     *
     * @param uri
     * @return
     */
    public static String test(URI uri, String name, String value) {
        LOGGER.info("发起请求： uri: {}", uri);
        HttpGet get = new HttpGet(uri);
        String result = null;
        get.setHeader(name, value);
        try {
            long start = System.currentTimeMillis();
            HttpResponse response = HTTP_CLIENT.execute(get);
            HttpEntity entity = response.getEntity();
            LOGGER.info("请求响应： {}", response.getStatusLine().getStatusCode());
            result = analysisResp(entity.getContent());
            LOGGER.info("请求成功！ uri: {}, response: {}", uri, result);
            EntityUtils.consume(entity);
            long spend = System.currentTimeMillis() - start;
            if (spend > 1000) {
            }
        } catch (IOException e) {
            // LOGGER.error("请求失败! uri: {}, headers: {}", uri, Arrays.toString(headers));
            LOGGER.error(e.getMessage(), e);
        } finally {
            get.releaseConnection();
        }
        // Logger.i(HttpUtil.class, "get request : "+ uri + ", result ：" + result);
        return result;
    }

    public static String testPosts(String server, String name, Header... headers) {
        return testPost(URI.create(server), name, headers);
    }

    public static String testPost(URI uri, String input, Header... headers) {
        LOGGER.info("发起请求! uri: {}, input: {}, headers: {}", uri, input, Arrays.toString(headers));
        String phpSessID = "";
        HttpPost post = new HttpPost(uri);
        String result = null;
        if (headers != null && headers.length > 0) {
            post.setHeaders(headers);
        }
        try {
            long start = System.currentTimeMillis();

            if (input != null) {
                post.setEntity(new StringEntity(input, "UTF-8"));
            }
            HttpResponse response = HTTP_CLIENT.execute(post);
            Header firstHeader = response.getFirstHeader("Set-Cookie");
            String value1 = firstHeader.getValue();
            System.out.println(value1);
            String[] split = value1.split(";");
            String s = split[0];
            String[] splits = s.split("=");
            phpSessID = splits[1];
            LOGGER.info("请求响应码! uri: {}, code: {} ", uri, response.getStatusLine().getStatusCode());
            HttpEntity entity = response.getEntity();
            result = analysisResp(entity.getContent());
            LOGGER.info("请求成功 ! uri: {}, result: {}", uri, result);
            EntityUtils.consume(entity);
            long spend = System.currentTimeMillis() - start;
            if (spend > 1000) {
            }
        } catch (Exception e) {
            LOGGER.error("请求失败 ! uri: {}, input: {}, headers: {}", uri, input, Arrays.toString(headers));
            LOGGER.error(e.getMessage(), e);
        } finally {
            post.releaseConnection();
        }
        // Logger.i(HttpUtil.class, "post request : " + uri + ", result : " + result);
        return phpSessID;
    }
}